Skip to content

fix(cli): detect WinGet Claude Code on Windows - #6647

Merged
diegosouzapw merged 7 commits into
diegosouzapw:release/v3.8.47from
enjoyer-hub:fix/windows-claude-winget-detection
Jul 9, 2026
Merged

diegosouzapw merged 7 commits into
diegosouzapw:release/v3.8.47from
enjoyer-hub:fix/windows-claude-winget-detection

Conversation

@enjoyer-hub

Copy link
Copy Markdown
Contributor

Summary

  • add the WinGet Anthropic Claude Code install location to Claude CLI known paths on Windows
  • cover the path with a CLI runtime regression test

Why

WinGet installs Claude Code at %LOCALAPPDATA%\Microsoft\WinGet\Packages\Anthropic.ClaudeCode_Microsoft.Winget.Source_8wekyb3d8bbwe\claude.exe, which was not in OmniRoute's fallback lookup list. Users could work around it with CLI_CLAUDE_BIN, but OmniRoute should detect the WinGet install automatically.

Test

  • node --max-old-space-size=8192 --import tsx/esm --import ./open-sse/utils/setupPolyfill.ts --import ./tests/_setup/isolateDataDir.ts --test --test-force-exit tests/unit/cli-runtime-detection.test.ts

Diego Rodrigues de Sa e Souza and others added 4 commits July 7, 2026 23:10
… (ABI 148) (diegosouzapw#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes diegosouzapw#6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)
…iegosouzapw#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (diegosouzapw#6605).
…7) + production deps bump (diegosouzapw#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes diegosouzapw#6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from diegosouzapw#6605 which passed the smoke. Not this diff.)
@ghost
ghost requested a review from diegosouzapw as a code owner July 8, 2026 11:22

ghost left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for detecting the WinGet installation path of Claude Code on Windows and includes a corresponding unit test. The reviewer suggested mocking the process.env.LOCALAPPDATA environment variable in the test to ensure it is robust and independent of the host environment.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +26 to +45
it("should include the WinGet Anthropic.ClaudeCode install path", () => {
const localAppData = process.env.LOCALAPPDATA;
const expected = localAppData
? path.join(
localAppData,
"Microsoft",
"WinGet",
"Packages",
"Anthropic.ClaudeCode_Microsoft.Winget.Source_8wekyb3d8bbwe",
"claude.exe"
)
: null;

if (process.platform !== "win32" || !expected) return;

assert.ok(
getKnownToolPaths("claude").includes(expected),
"Claude Code installed by WinGet should be discoverable without CLI_CLAUDE_BIN"
);
});

ghost Jul 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The test currently relies on the host's actual process.env.LOCALAPPDATA environment variable. If LOCALAPPDATA is missing or is set to a custom path outside the allowed parent directories (which are validated against the user's home directory in validateEnvPath), the test will fail or silently skip. Mocking process.env.LOCALAPPDATA to a deterministic, valid path (such as path.join(os.homedir(), 'AppData', 'Local')) ensures the test is robust and independent of the host environment.

  it("should include the WinGet Anthropic.ClaudeCode install path", () => {
    if (process.platform !== "win32") return;

    const originalLocalAppData = process.env.LOCALAPPDATA;
    const home = os.homedir();
    const testLocalAppData = path.join(home, "AppData", "Local");

    process.env.LOCALAPPDATA = testLocalAppData;
    try {
      const expected = path.join(
        testLocalAppData,
        "Microsoft",
        "WinGet",
        "Packages",
        "Anthropic.ClaudeCode_Microsoft.Winget.Source_8wekyb3d8bbwe",
        "claude.exe"
      );

      assert.ok(
        getKnownToolPaths("claude").includes(expected),
        "Claude Code installed by WinGet should be discoverable without CLI_CLAUDE_BIN"
      );
    } finally {
      if (originalLocalAppData !== undefined) {
        process.env.LOCALAPPDATA = originalLocalAppData;
      } else {
        delete process.env.LOCALAPPDATA;
      }
    }
  });

ghost commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Thanks for this — clean, small, well-scoped fix. The new WinGet path sits correctly inside the existing isWindows()/localAppData guard right next to the other two Claude Code fallback paths, and I ran tests/unit/cli-runtime-detection.test.ts locally (14/14 passing, including your new case). This is merge-ready as-is; we'll just retarget the base branch from main to our active release branch (release/v3.8.47) before landing, which is our normal workflow for all incoming PRs, not specific to yours. Nice catch on the WinGet install path.

@ghost
ghost changed the base branch from main to release/v3.8.47 July 8, 2026 23:58
Diego Rodrigues de Sa e Souza and others added 3 commits July 9, 2026 04:53
…roxy files belong to diegosouzapw#6620, not this PR)

Restores electron/package-lock.json, electron/package.json, package-lock.json,
package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs
and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content.
The PR fork branched from a state of main that already includes diegosouzapw#6620 (proxy CONNECT
tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way
merge would otherwise silently carry that unrelated content into this doc-only PR.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…uzapw#6647 (1100->1110)

The file was already exactly at the frozen 1100-line cap on release/v3.8.47.
PR diegosouzapw#6647's WinGet Claude Code detection path adds 10 lines (irreducible —
the 62-char package folder name forces Prettier's 100-char width to break
the path.join call across the same multi-line form used by every other
long path in this function), tripping the Fast Quality Gates check:file-size
job. Bumping the frozen cap to the file's real new size per the documented
allowlist-with-justification policy (this is a pass/fail policy gate, not
the ratchet metrics system).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@ghost
ghost merged commit e697670 into diegosouzapw:release/v3.8.47 Jul 9, 2026
@ghost ghost mentioned this pull request Jul 11, 2026
@ghost ghost mentioned this pull request Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants